/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2007 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author:                                                              |
  +----------------------------------------------------------------------+
*/

/* $Id: header,v 1.16.2.1.2.1 2007/01/01 19:32:09 iliaa Exp $ */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_nmdb.h"
#include "nmdb.h"




/* If you declare any globals in php_nmdb.h uncomment this:
ZEND_DECLARE_MODULE_GLOBALS(nmdb)
*/

/* True global resources - no need for thread safety here */
static int le_nmdb;

/* {{{ nmdb_functions[]
 *
 * Every user visible function must have an entry in nmdb_functions[].
 */
zend_function_entry nmdb_functions[] = {
	PHP_FE(nmdb_init,	NULL)
	PHP_FE(nmdb_add_tipc_server,	NULL)	
	PHP_FE(nmdb_add_tcp_server,	NULL)
	PHP_FE(nmdb_add_udp_server,	NULL)
	PHP_FE(nmdb_add_sctp_server,	NULL)
	PHP_FE(nmdb_free,	NULL)
	PHP_FE(nmdb_set,	NULL)
	PHP_FE(nmdb_set_sync,	NULL)
	PHP_FE(nmdb_cache_set,	NULL)
	PHP_FE(nmdb_get,	NULL)
	PHP_FE(nmdb_cache_get,	NULL)
	PHP_FE(nmdb_del,	NULL)
	PHP_FE(nmdb_del_sync,	NULL)
	PHP_FE(nmdb_cache_del,	NULL)
	PHP_FE(nmdb_cas,	NULL)
	PHP_FE(nmdb_cache_cas,	NULL)
	PHP_FE(nmdb_incr,	NULL)
	PHP_FE(nmdb_cache_incr,	NULL)
	{NULL, NULL, NULL}	/* Must be the last line in nmdb_functions[] */
};
/* }}} */

/* {{{ nmdb_module_entry
 */
zend_module_entry nmdb_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
	STANDARD_MODULE_HEADER,
#endif
	"nmdb",
	nmdb_functions,
	PHP_MINIT(nmdb),
	PHP_MSHUTDOWN(nmdb),
	PHP_RINIT(nmdb),		/* Replace with NULL if there's nothing to do at request start */
	PHP_RSHUTDOWN(nmdb),	/* Replace with NULL if there's nothing to do at request end */
	PHP_MINFO(nmdb),
#if ZEND_MODULE_API_NO >= 20010901
	"0.1", /* Replace with version number for your extension */
#endif
	STANDARD_MODULE_PROPERTIES
};
/* }}} */

#ifdef COMPILE_DL_NMDB
ZEND_GET_MODULE(nmdb)
#endif


static void php_nmdb_dtor(
                    zend_rsrc_list_entry *rsrc TSRMLS_DC)
{
	nmdb_t *nmdb_p = (nmdb_t*) rsrc->ptr;
	if (nmdb_p) {
		nmdb_free(nmdb_p);
	}
}



/* {{{ PHP_INI
 */
/* Remove comments and fill if you need to have entries in php.ini
PHP_INI_BEGIN()
    STD_PHP_INI_ENTRY("nmdb.global_value",      "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_nmdb_globals, nmdb_globals)
    STD_PHP_INI_ENTRY("nmdb.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_nmdb_globals, nmdb_globals)
PHP_INI_END()
*/
/* }}} */

/* {{{ php_nmdb_init_globals
 */
/* Uncomment this function if you have INI entries
static void php_nmdb_init_globals(zend_nmdb_globals *nmdb_globals)
{
	nmdb_globals->global_value = 0;
	nmdb_globals->global_string = NULL;
}
*/
/* }}} */

/* {{{ PHP_MINIT_FUNCTION
 */
PHP_MINIT_FUNCTION(nmdb)
{

	/* If you have INI entries, uncomment these lines 
	REGISTER_INI_ENTRIES();
	*/
	le_nmdb = zend_register_list_destructors_ex(
                php_nmdb_dtor, NULL, PHP_NMDB_RES_NAME,
                module_number);

	return SUCCESS;
}
/* }}} */

/* {{{ PHP_MSHUTDOWN_FUNCTION
 */
PHP_MSHUTDOWN_FUNCTION(nmdb)
{
	/* uncomment this line if you have INI entries
	UNREGISTER_INI_ENTRIES();
	*/
	return SUCCESS;
}
/* }}} */

/* Remove if there's nothing to do at request start */
/* {{{ PHP_RINIT_FUNCTION
 */
PHP_RINIT_FUNCTION(nmdb)
{
	return SUCCESS;
}
/* }}} */

/* Remove if there's nothing to do at request end */
/* {{{ PHP_RSHUTDOWN_FUNCTION
 */
PHP_RSHUTDOWN_FUNCTION(nmdb)
{
	return SUCCESS;
}
/* }}} */

/* {{{ PHP_MINFO_FUNCTION
 */
PHP_MINFO_FUNCTION(nmdb)
{
	php_info_print_table_start();
	php_info_print_table_header(2, "nmdb support", "enabled");
	php_info_print_table_end();

	/* Remove comments if you have entries in php.ini
	DISPLAY_INI_ENTRIES();
	*/
}
/* }}} */


/* {{{ proto resource nmdb_init()
    */
PHP_FUNCTION(nmdb_init)
{
	if (ZEND_NUM_ARGS() != 0) {
		WRONG_PARAM_COUNT;
	}
	nmdb_t* nmdb_p;

	nmdb_p = nmdb_init();
	
	ZEND_REGISTER_RESOURCE(return_value, nmdb_p, le_nmdb);
}
/* }}} */

/* {{{ proto int nmdb_add_tipc_server(resource db, int port)
    */
PHP_FUNCTION(nmdb_add_tipc_server)
{
	char *addr = NULL;
	int argc = ZEND_NUM_ARGS();
	int db_id = -1;
	int addr_len;
	long port;
	int ret = 0;
	zval *db = NULL;
	nmdb_t *nmdb_p;

	if (zend_parse_parameters(argc TSRMLS_CC, "rsl", &db, &port) == FAILURE) 
		return;

	if (db) {
		ZEND_FETCH_RESOURCE(nmdb_p, nmdb_t *, &db, db_id,
	        PHP_NMDB_RES_NAME, le_nmdb);
		if (nmdb_p) {
			ret = nmdb_add_tipc_server(nmdb_p, port);
			RETURN_LONG(ret);
		}
	}
}
/* }}} */

/* {{{ proto int nmdb_add_tcp_server(resource db, string addr, int port)
    */
PHP_FUNCTION(nmdb_add_tcp_server)
{
	char *addr = NULL;
	int argc = ZEND_NUM_ARGS();
	int db_id = -1;
	int addr_len;
	long port;
	int ret = 0;
	zval *db = NULL;
	nmdb_t *nmdb_p;

	if (zend_parse_parameters(argc TSRMLS_CC, "rsl", &db, &addr, &addr_len, &port) == FAILURE) 
		return;

	if (db) {
		ZEND_FETCH_RESOURCE(nmdb_p, nmdb_t *, &db, db_id,
	        PHP_NMDB_RES_NAME, le_nmdb);
		if (nmdb_p) {
			ret = nmdb_add_tcp_server(nmdb_p, addr, port);
			RETURN_LONG(ret);
		}
	}
}
/* }}} */

/* {{{ proto int nmdb_add_udp_server(resource db, string addr, int port)
    */
PHP_FUNCTION(nmdb_add_udp_server)
{
	char *addr = NULL;
	int argc = ZEND_NUM_ARGS();
	int db_id = -1;
	int addr_len;
	long port;
	int ret = 0;
	zval *db = NULL;
	nmdb_t *nmdb_p;

	if (zend_parse_parameters(argc TSRMLS_CC, "rsl", &db, &addr, &addr_len, &port) == FAILURE) 
		return;

	if (db) {
		ZEND_FETCH_RESOURCE(nmdb_p, nmdb_t *, &db, db_id,
	        PHP_NMDB_RES_NAME, le_nmdb);
		if (nmdb_p) {
			ret = nmdb_add_udp_server(nmdb_p, addr, port);
			RETURN_LONG(ret);
		}
	}
}
/* }}} */

/* {{{ proto int nmdb_add_sctp_server(resource db, string addr, int port)
    */
PHP_FUNCTION(nmdb_add_sctp_server)
{
	char *addr = NULL;
	int argc = ZEND_NUM_ARGS();
	int db_id = -1;
	int addr_len;
	long port;
	int ret = 0;
	zval *db = NULL;
	nmdb_t *nmdb_p;

	if (zend_parse_parameters(argc TSRMLS_CC, "rsl", &db, &addr, &addr_len, &port) == FAILURE) 
		return;

	if (db) {
		ZEND_FETCH_RESOURCE(nmdb_p, nmdb_t *, &db, db_id,
	        PHP_NMDB_RES_NAME, le_nmdb);
		if (nmdb_p) {
			ret = nmdb_add_sctp_server(nmdb_p, addr, port);
			RETURN_LONG(ret);
		}
	}
}
/* }}} */

/* {{{ proto int nmdb_free(resource db)
    */
PHP_FUNCTION(nmdb_free)
{
	int argc = ZEND_NUM_ARGS();
	int db_id = -1;
	zval *db = NULL;
	nmdb_t *nmdb_p;
	int ret = -1;
	

	if (zend_parse_parameters(argc TSRMLS_CC, "r", &db) == FAILURE) 
		return;

	if (db) {
		ZEND_FETCH_RESOURCE(nmdb_p, nmdb_t *, &db, db_id,
	        PHP_NMDB_RES_NAME, le_nmdb);
		
		zend_hash_index_del(&EG(regular_list),
						Z_RESVAL_P(db));
		RETURN_TRUE;
	}
	RETURN_LONG(-1);
}
/* }}} */

/* {{{ proto int nmdb_set(resource db, string key, string value)
    */
PHP_FUNCTION(nmdb_set)
{
	char *key = NULL;
	char *value = NULL;
	int argc = ZEND_NUM_ARGS();
	int db_id = -1;
	int key_len;
	int value_len;
	zval *db = NULL;
	nmdb_t *nmdb_p;
	int ret = -1;

	if (zend_parse_parameters(argc TSRMLS_CC, "rss", &db, &key, &key_len, &value, &value_len) == FAILURE) 
		return;

	if (db) {
		ZEND_FETCH_RESOURCE(nmdb_p, nmdb_t *, &db, db_id,
	        PHP_NMDB_RES_NAME, le_nmdb);
		if (nmdb_p) {
			ret = nmdb_set(nmdb_p, key, key_len, value, value_len + 1);
			
		}
		RETURN_LONG(ret);
	}
}
/* }}} */

/* {{{ proto int nmdb_set_sync(resource db, string key, string value)
    */
PHP_FUNCTION(nmdb_set_sync)
{
	char *key = NULL;
	char *value = NULL;
	int argc = ZEND_NUM_ARGS();
	int db_id = -1;
	int key_len;
	int value_len;
	zval *db = NULL;
	nmdb_t *nmdb_p;
	int ret = -1;

	if (zend_parse_parameters(argc TSRMLS_CC, "rss", &db, &key, &key_len, &value, &value_len) == FAILURE) 
		return;

	if (db) {
		ZEND_FETCH_RESOURCE(nmdb_p, nmdb_t *, &db, db_id,
	        PHP_NMDB_RES_NAME, le_nmdb);
		if (nmdb_p) {
			ret = nmdb_set_sync(nmdb_p, key, key_len, value, value_len + 1);
			
		}
		RETURN_LONG(ret);
	}
}
/* }}} */

/* {{{ proto int nmdb_cache_set(resource db, string key, string value)
    */
PHP_FUNCTION(nmdb_cache_set)
{
	char *key = NULL;
	char *value = NULL;
	int argc = ZEND_NUM_ARGS();
	int db_id = -1;
	int key_len;
	int value_len;
	zval *db = NULL;
	nmdb_t *nmdb_p;
	int ret = -1;

	if (zend_parse_parameters(argc TSRMLS_CC, "rss", &db, &key, &key_len, &value, &value_len) == FAILURE) 
		return;

	if (db) {
		ZEND_FETCH_RESOURCE(nmdb_p, nmdb_t *, &db, db_id,
	        PHP_NMDB_RES_NAME, le_nmdb);
		if (nmdb_p) {
			ret = nmdb_cache_set(nmdb_p, key, key_len, value, value_len + 1);
			
		}
		RETURN_LONG(ret);
	}
}
/* }}} */

/* {{{ proto string nmdb_get(resource db, string key)
    */
PHP_FUNCTION(nmdb_get)
{
	char *key = NULL;
	int argc = ZEND_NUM_ARGS();
	int db_id = -1;
	int key_len;
	zval *db = NULL;
	nmdb_t *nmdb_p;
	char* buffer = NULL;
	int value_len = 0;
	int ret;

	if (zend_parse_parameters(argc TSRMLS_CC, "rs", &db, &key, &key_len) == FAILURE) 
		return;

	if (db) {
		ZEND_FETCH_RESOURCE(nmdb_p, nmdb_t *, &db, db_id,
	        PHP_NMDB_RES_NAME, le_nmdb);
		if (nmdb_p) {
			buffer = (char*) emalloc(PHP_NMDB_BUFFER_SIZE * sizeof(char));
			value_len = nmdb_get(nmdb_p, key, key_len, buffer, PHP_NMDB_BUFFER_SIZE);
			if (value_len > 0) {
				RETVAL_STRINGL(buffer, value_len - 1, 1);
			}
			efree(buffer);
			return;	
		}
	}
}
/* }}} */

/* {{{ proto string nmdb_cache_get(resource db, string key)
    */
PHP_FUNCTION(nmdb_cache_get)
{
	char *key = NULL;
	int argc = ZEND_NUM_ARGS();
	int db_id = -1;
	int key_len;
	zval *db = NULL;
	nmdb_t *nmdb_p;
	char* buffer = NULL;
	int value_len = 0;
	int ret;

	if (zend_parse_parameters(argc TSRMLS_CC, "rs", &db, &key, &key_len) == FAILURE) 
		return;

	if (db) {
		ZEND_FETCH_RESOURCE(nmdb_p, nmdb_t *, &db, db_id,
	        PHP_NMDB_RES_NAME, le_nmdb);
		if (nmdb_p) {
			buffer = (char*) emalloc(PHP_NMDB_BUFFER_SIZE * sizeof(char));
			value_len = nmdb_cache_get(nmdb_p, key, key_len, buffer, PHP_NMDB_BUFFER_SIZE);
			if (value_len > 0) {
				RETVAL_STRINGL(buffer, value_len - 1, 1);
			}
			efree(buffer);
			return;	
		}
	}
}
/* }}} */

/* {{{ proto int nmdb_del(resource db, string key)
    */
PHP_FUNCTION(nmdb_del)
{
	char *key = NULL;
	int argc = ZEND_NUM_ARGS();
	int db_id = -1;
	int key_len;
	nmdb_t *nmdb_p;
	zval *db = NULL;
	int ret = 0;

	if (zend_parse_parameters(argc TSRMLS_CC, "rs", &db, &key, &key_len) == FAILURE) 
		return;

	if (db) {
		ZEND_FETCH_RESOURCE(nmdb_p, nmdb_t *, &db, db_id,
	        PHP_NMDB_RES_NAME, le_nmdb);
		if (nmdb_p) {
			ret = nmdb_del(nmdb_p, key, key_len);
			RETURN_LONG(ret);
		}
	}
}
/* }}} */

/* {{{ proto int nmdb_del_sync(resource db, string key)
    */
PHP_FUNCTION(nmdb_del_sync)
{
	char *key = NULL;
	int argc = ZEND_NUM_ARGS();
	int db_id = -1;
	int key_len;
	nmdb_t *nmdb_p;
	zval *db = NULL;
	int ret = 0;

	if (zend_parse_parameters(argc TSRMLS_CC, "rs", &db, &key, &key_len) == FAILURE) 
		return;

	if (db) {
		ZEND_FETCH_RESOURCE(nmdb_p, nmdb_t *, &db, db_id,
	        PHP_NMDB_RES_NAME, le_nmdb);
		if (nmdb_p) {
			ret = nmdb_del_sync(nmdb_p, key, key_len);
			RETURN_LONG(ret);
		}
	}
}
/* }}} */

/* {{{ proto int nmdb_cache_del(resource db, string key)
    */
PHP_FUNCTION(nmdb_cache_del)
{
	char *key = NULL;
	int argc = ZEND_NUM_ARGS();
	int db_id = -1;
	int key_len;
	nmdb_t *nmdb_p;
	zval *db = NULL;
	int ret = 0;

	if (zend_parse_parameters(argc TSRMLS_CC, "rs", &db, &key, &key_len) == FAILURE) 
		return;

	if (db) {
		ZEND_FETCH_RESOURCE(nmdb_p, nmdb_t *, &db, db_id,
	        PHP_NMDB_RES_NAME, le_nmdb);
		if (nmdb_p) {
			ret = nmdb_del_sync(nmdb_p, key, key_len);
			RETURN_LONG(ret);
		}
	}
}
/* }}} */

/* {{{ proto int nmdb_cas(resource db, string key, string old_value, string new_value)
    */
PHP_FUNCTION(nmdb_cas)
{
	char *key = NULL;
	char *old_value = NULL;
	char *new_value = NULL;
	int argc = ZEND_NUM_ARGS();
	int db_id = -1;
	int key_len;
	int old_value_len;
	int new_value_len;
	zval *db = NULL;
	int ret;
	nmdb_t *nmdb_p;

	if (zend_parse_parameters(argc TSRMLS_CC, "rsss", &db, &key, &key_len, &old_value, &old_value_len, &new_value, &new_value_len) == FAILURE) 
		return;

	if (db) {
		ZEND_FETCH_RESOURCE(nmdb_p, nmdb_t *, &db, db_id,
	        PHP_NMDB_RES_NAME, le_nmdb);
		if (nmdb_p) {
			ret = nmdb_cas(nmdb_p, key, key_len, old_value, old_value_len + 1, new_value, new_value_len + 1);
			RETURN_LONG(ret);
		}
	}
}
/* }}} */

/* {{{ proto int nmdb_cache_cas(resource db, string key, string old_value, string new_value)
    */
PHP_FUNCTION(nmdb_cache_cas)
{
	char *key = NULL;
	char *old_value = NULL;
	char *new_value = NULL;
	int argc = ZEND_NUM_ARGS();
	int db_id = -1;
	int key_len;
	int old_value_len;
	int new_value_len;
	zval *db = NULL;
	int ret;
	nmdb_t *nmdb_p;

	if (zend_parse_parameters(argc TSRMLS_CC, "rsss", &db, &key, &key_len, &old_value, &old_value_len, &new_value, &new_value_len) == FAILURE) 
		return;

	if (db) {
		ZEND_FETCH_RESOURCE(nmdb_p, nmdb_t *, &db, db_id,
	        PHP_NMDB_RES_NAME, le_nmdb);
		if (nmdb_p) {
			ret = nmdb_cache_cas(nmdb_p, key, key_len, old_value, old_value_len + 1, new_value, new_value_len + 1);
			RETURN_LONG(ret);
		}
	}
}
/* }}} */

/* {{{ proto int nmdb_incr(resource db, string key, int increment)
    */
PHP_FUNCTION(nmdb_incr)
{
	char *key = NULL;
	int argc = ZEND_NUM_ARGS();
	int db_id = -1;
	int key_len;
	long increment;
	zval *db = NULL;
	nmdb_t *nmdb_p;
	int ret;

	if (zend_parse_parameters(argc TSRMLS_CC, "rsl", &db, &key, &key_len, &increment) == FAILURE) 
		return;

	if (db) {
		ZEND_FETCH_RESOURCE(nmdb_p, nmdb_t *, &db, db_id,
	        PHP_NMDB_RES_NAME, le_nmdb);
		if (nmdb_p) {
			ret = nmdb_incr(nmdb_p, key, key_len, increment);
			RETURN_LONG(ret);
		}
	}
}
/* }}} */

/* {{{ proto int nmdb_cache_incr(resource db, string key, int increment)
    */
PHP_FUNCTION(nmdb_cache_incr)
{
	char *key = NULL;
	int argc = ZEND_NUM_ARGS();
	int db_id = -1;
	int key_len;
	long increment;
	zval *db = NULL;
	nmdb_t *nmdb_p;
	int ret;

	if (zend_parse_parameters(argc TSRMLS_CC, "rsl", &db, &key, &key_len, &increment) == FAILURE) 
		return;

	if (db) {
		ZEND_FETCH_RESOURCE(nmdb_p, nmdb_t *, &db, db_id,
	        PHP_NMDB_RES_NAME, le_nmdb);
		if (nmdb_p) {
			ret = nmdb_cache_incr(nmdb_p, key, key_len, increment);
			RETURN_LONG(ret);
		}
	}
}
/* }}} */


/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
